package com.cw.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cw.common.constant.Response;
import com.cw.common.method.SendCardMsg;
import com.cw.entity.DaySurgeryLog;
import com.cw.entity.MqLog;
import com.cw.entity.MsgInfo;
import com.cw.entity.WeChatLog;
import com.cw.mapper2.DaySurgeryLogMapper;
import com.cw.mapper2.MqLogMapper;
import com.cw.mapper2.WeChatLogMapper;
import com.cw.util.MQMsg;
import com.cw.util.UUIDUtil;
import com.cw.vo.DaySurgeryVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author xnd
 * @since 2023/9/18 8:44
 */
@Component
@EnableAsync
@Slf4j
public class DaySurgeryTask {

    @Autowired
    private WeChatLogMapper weChatLogMapper;

    @Autowired
    private MqLogMapper mqLogMapper;

    @Autowired
    private DaySurgeryLogMapper daySurgeryLogMapper;

    private MQMsg mqMsg = new MQMsg();

    //    每小时执行一次
//    @Scheduled(cron = "0 0 0/1 * * ?")
//    每半个小时执行一次
    @Scheduled(cron = "0 0/30 * * * ?")
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void daySurgery() {
        List<DaySurgeryVO> list = mqLogMapper.listMessage();
        LambdaQueryWrapper<DaySurgeryLog> lambdaQueryWrapperDayLog = new LambdaQueryWrapper<>();
        List<DaySurgeryLog> daySurgeryLogs = daySurgeryLogMapper.selectList(lambdaQueryWrapperDayLog);
        if (!daySurgeryLogs.isEmpty()) {
            List<String> patientNoList = daySurgeryLogs.stream()
                    .map(DaySurgeryLog::getPatientNo)
                    .collect(Collectors.toList());
            //不包含patientNoList集合里的住院证，进行过滤
            list = list.stream().filter(t -> !patientNoList.contains(t.getPatientNo())).collect(Collectors.toList());
        }
        //避免MQ重复发送最优解
        AtomicInteger x = new AtomicInteger(0);
        AtomicInteger y = new AtomicInteger(0);
        list.forEach(t -> {
            DaySurgeryVO daySurgeryVo1 = new DaySurgeryVO();
            DaySurgeryLog daySurgeryLog = new DaySurgeryLog();
            BeanUtils.copyProperties(t, daySurgeryVo1);
            BeanUtils.copyProperties(daySurgeryVo1, daySurgeryLog);
            MsgInfo msgInfo = getMsgInfo(daySurgeryVo1);
            //判断条件 当ssjb <>‘四级’  and  remain_time>23  and   remain_time<24
            if (!"四级".equals(t.getSsjb())) {
                BigDecimal remainTime = t.getRemainTime();
                if (remainTime.compareTo(new BigDecimal("23")) >= 0 && remainTime.compareTo(new BigDecimal("24")) <= 0) {
                    //发送MQ
                    String msgId = setMsg(msgInfo);
                    //类型为企业微信
                    daySurgeryLog.setMsgType("0");
                    //记录一次日志
                    int insertWechat = daySurgeryLogMapper.insert(daySurgeryLog);
                    if (insertWechat == 0) {
                        log.error("微信日志记录失败------------------------------------------");
                        throw new RuntimeException("日志记录失败");
                    }
                    x.getAndIncrement();
                    //发送企业微信
                    if (msgInfo.getWechatAccountCode() != null && !msgInfo.getWechatAccountCode().isEmpty()) {
                        //企业微信返回josn消息体
                        try {
                            //发送企业微信消息
                            WeChatLog weChatLog = SendCardMsg.send5(msgInfo);
                            weChatLog.setMsgId(msgId);
                            LambdaQueryWrapper<WeChatLog> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                            lambdaQueryWrapper.eq(WeChatLog::getMsgId, msgId);
                            Integer integer = weChatLogMapper.selectCount(lambdaQueryWrapper);
                            //当msgid没有的时候才去插入，但是只要他大于0了，说明已经插入过了，那就过掉
                            if (integer == 0) {
                                weChatLogMapper.insert(weChatLog);
                                y.getAndIncrement();
                                //类型为HIS一体化
                                daySurgeryLog.setMsgType("1");
                                //记录一次日志
                                int insertMQ = daySurgeryLogMapper.insert(daySurgeryLog);
                                if (insertMQ == 0) {
                                    log.error("MQ日志记录失败------------------------------------------");
                                    throw new RuntimeException("日志记录失败");
                                }
                            }
                        } catch (IOException e) {
                            int a = 0;
                        }
                    }
                }
            }
            //判断条件 当ssjb =‘四级’  and  remain_time>47  and   remain_time<48
            if ("四级".equals(t.getSsjb())) {
                BigDecimal remainTime = t.getRemainTime();
                if (remainTime.compareTo(new BigDecimal("47")) >= 0 && remainTime.compareTo(new BigDecimal("48")) <= 0) {
                    //发送MQ
                    x.getAndIncrement();
                    String msgId = setMsg(msgInfo);
                    //类型为企业微信
                    daySurgeryLog.setMsgType("0");
                    //记录一次日志
                    int insertWechat = daySurgeryLogMapper.insert(daySurgeryLog);
                    if (insertWechat == 0) {
                        log.error("微信日志记录失败------------------------------------------");
                        throw new RuntimeException("日志记录失败");
                    }
                    //发送企业微信
                    if (msgInfo.getWechatAccountCode() != null && !msgInfo.getWechatAccountCode().isEmpty()) {
                        //企业微信返回josn消息体
                        try {
                            //发送企业微信消息
                            WeChatLog weChatLog = SendCardMsg.send5(msgInfo);
                            weChatLog.setMsgId(msgId);
                            LambdaQueryWrapper<WeChatLog> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                            lambdaQueryWrapper.eq(WeChatLog::getMsgId, msgId);
                            Integer integer = weChatLogMapper.selectCount(lambdaQueryWrapper);
                            if (integer == 0) {
                                weChatLogMapper.insert(weChatLog);
                                y.getAndIncrement();
                                //类型为HIS一体化
                                daySurgeryLog.setMsgType("1");
                                //记录一次日志
                                int insertMq = daySurgeryLogMapper.insert(daySurgeryLog);
                                if (insertMq == 0) {
                                    log.error("MQ日志记录失败------------------------------------------");
                                    throw new RuntimeException("日志记录失败");
                                }
                            }
                        } catch (IOException e) {
                            int a = 0;
                        }
                    }
                }
            }

        });
        int x1 = x.get();
        int y1 = y.get();
        if (x1 != y1) {
            throw new RuntimeException("发送失败");
        }
    }

    private String setMsg(MsgInfo msgInfo) {
        // 设定用户
        mqMsg.setUserName("S01");
        // 设定密码
        mqMsg.setPassword("123456");
        // 设定通道池
        mqMsg.setQueueManagerName("QMGR.P01");
        // 设定消息频道
        mqMsg.setChannel("PS35035");
        mqMsg.setMsgTitle(msgInfo.getTitle());
        //发给个人
        mqMsg.setPatName(msgInfo.getName());
        mqMsg.setMsgTitle(msgInfo.getTitle());
        mqMsg.setMessageType("1");
        // 设定消息内容
        mqMsg.setMsgContent(msgInfo.getCirculateMsgContent());
        mqMsg.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        mqMsg.setSenderCode(msgInfo.getEmplCode());        // 设定发送者工号
        mqMsg.setSenderName(msgInfo.getEmplName());        // 设定发送者姓名
        mqMsg.setBedNum(msgInfo.getBedNum());        // 设定床位号
        mqMsg.setWardCode(msgInfo.getNurseCellCode());    // 病区代码
        // 设定病区名称
        mqMsg.setWardName(msgInfo.getNurseCellName());
        // 设定院区编号
        mqMsg.setHospDistrictCode(msgInfo.getYard());
        // 设定院区
        mqMsg.setHostDistrictName(msgInfo.getYardName());
        mqMsg.setReciveCode(msgInfo.getEmplCode());
        mqMsg.setReciveName(msgInfo.getEmplName());
        String xmlString = mqMsg.createXMLString(mqMsg);
        MqLog mqLog = new MqLog();
        String uuid = UUIDUtil.uuid();
        mqLog.setId(uuid);
        mqLog.setRequestMsg(xmlString);
        mqLog.setRequestDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        mqLog.setSenderCode(msgInfo.getEmplCode());
        mqLog.setSenderName(msgInfo.getEmplName());
        String msgId = mqMsg.putMsg(xmlString);
        mqLog.setMsgId(msgId);
        if (!Objects.equals(msgId, "")) {
            mqLog.setResponseType("success");
        } else {
            mqLog.setResponseType("fail");
        }
        //之前发现插入两次的情况，这里判断一下，去查一遍库，当他=0的时候才去走插入，只要有一条，就不插了
        LambdaQueryWrapper<MqLog> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MqLog::getMsgId, msgId);
        Integer integer = mqLogMapper.selectCount(lambdaQueryWrapper);
        if (integer == 0) {
            mqLogMapper.insert(mqLog);
        }
        return msgId;
    }

    private MsgInfo getMsgInfo(DaySurgeryVO daySurgeryVO) {
        MsgInfo info = new MsgInfo();
        info.setEmplCode(daySurgeryVO.getChiefDocCode());
        info.setEmplName(daySurgeryVO.getChiefDocName());
        info.setPatientNo(daySurgeryVO.getPatientNo());
        info.setBedNum(daySurgeryVO.getBedNo());
        info.setName(daySurgeryVO.getName());
        info.setYardName("三香");
        info.setYard("1");
        info.setNurseCellCode(daySurgeryVO.getNurseCellCode());
        info.setNurseCellName(daySurgeryVO.getNurseCellName());
        info.setTitle("日间手术消息推送");
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String inDate = daySurgeryVO.getInDate().format(fmt);
        String context =
                "您的日间手术病人" + daySurgeryVO.getName() + "(" + daySurgeryVO.getNurseCellName() + "," + "床位号" + daySurgeryVO.getBedNo() + "," + "住院号" + daySurgeryVO.getPatientNo() + "," + "入院时间" + inDate + ")" + "," + "已住院" + daySurgeryVO.getRemainTime() + "小时" + "," + "请及时开立出院医嘱" + "," + "办理出院手续。";
        info.setCirculateMsgContent(context);
        if (daySurgeryVO.getChiefDocCode() != null) {
            info.setWechatAccountCode(daySurgeryVO.getChiefDocCode());
        }
        return info;
    }
}
